# coding=utf-8

import web
from web.utils import uniq, storage, memoize

import settings
import utils
import define
import redirect

import controllers.afflatus.models as afflatus_models
import controllers.discounts.models as discount_models
import controllers.projects.models as proj_models
import controllers.users.models as user_models
from controllers.users import UserSession, auth_login
from controllers.users.views import Subscribe
from controllers.users.forms import login_form

render = settings.FRONT_RENDER

class AjaxCommand(object):
    """
    处理Ajax命令的视图
    """
    def POST(self, cmd):
        return {
                "login": self.auth_login,
                "aff_follow": self.aff_follow,
                "aff_unfollow": self.aff_unfollow,
                "aff_beento": self.aff_beento,
                "aff_unbeento": self.aff_unbeento,
                "load_partners": self.load_partners,
                "exists_email": self.exists_email,
                "reg": self.register,
                "login_bind": self.login_bind,
                "check_login": self.check_login,
            }[cmd]()

    def check_login(self):
        """登录校验"""
        form = login_form()
        if not form.validates():
            for i in form.inputs:
                if i.note:
                    return "{'status': 3, 'msg': '%s'}" % i.note
        # 登录
        if user_models.login(form.email.value
                , form.pwd.value
                , form.remeber.checked):
            # 登录成功
            return "{'status': 0}"
        # 登录失败
        return "{'status': 1, 'msg': '登录失败，邮箱或密码错误。'}"

    def login_bind(self):
        """登录绑定连接"""
        # 会话是否有效
        cook = UserSession.resolve_reg_cookie()
        if not (cook and cook.user and cook.token):
            return "{'status': 2, 'msg': '会话超时。'}"

        form = login_form()
        if not form.validates():
            for i in form.inputs:
                if i.note:
                    return "{'status': 3, 'msg': '%s'}" % i.note
                
        # 登录
        if user_models.login(form.email.value
                , form.pwd.value
                , form.remeber.value
                , self.user_bind):
            # 登录成功
            return "{'status': 0, 'url':'%s'}" % redirect.combine(form.url.value, authed = 3)
        # 登录失败
        return "{'status': 1, 'msg': '登录失败，邮箱或密码错误。'}"

    def user_bind(self, usr, remeber):
        """绑定用户信息"""
        # 获取连接临时信息
        cook = UserSession.resolve_reg_cookie()
        if cook:
            # 临时信息有效
            # 开始绑定
            if user_models.login_bind(usr, cook):
                # 清空临时cookie
                UserSession.clear_reg_cookie()

    def register(self):
        """注册"""
        # 会话是否有效
        cook = UserSession.resolve_reg_cookie()
        if not cook:
            return "{'status': 2, 'msg': '会话超时。'}"

        form = web.input(email = None
                , pswd = None
                , pscwd = None
                , depart = None
                , url = '')
        if not (form.email and form.pswd and form.pscwd):
            # 未提交任何内容
            return "{'status':1, 'msg':'请先完成表单录入。'}"
        if not utils.is_email(form.email):
            # email格式错误
            return "{'status':2, 'msg':'该邮箱格式错误！'}"
        if user_models.exists_email(form.email):
            # email已经被注册
            return "{'status': 3, 'msg': '该邮箱已被注册，换一个试试。'}"
        if not form.pswd:
            # 未输入密码
            return "{'status':4, 'msg':'请输入密码!'}"
        if cmp(form.pswd, form.pscwd) != 0:
            # 密码不一致
            return "{'status':5, 'msg':'密码与确认密码不一致！'}"

        cook = UserSession.resolve_reg_cookie()
        # 开始注册
        if user_models.register_bind(form, cook):
            # 这里发送确认邮件
            Subscribe.subscribe_request(cook.user['id']
                    , form.email
                    , form.depart
                    , form.url)
            # 清空临时cookie
            UserSession.clear_reg_cookie()
            # 返回成功状态
            return "{'status':0, 'po':'http://%s'}" % utils.post_office(form.email)

        # 注册失败
        return "{'status':255}"


    def exists_email(self):
        """判断邮件是否已经被注册"""
        email = web.input().get('email', None)
        if not utils.is_email(email):
            # email格式错误
            return "{'status': 1, 'msg': '该邮箱格式错误！'}"
        if user_models.exists_email(email):
            # email已经被注册
            return "{'status': 2, 'msg': '该邮箱已被注册，换一个试试。'}"

        return {'status': 0}

    def load_partners(self):
        """
        读取合作商家列表
        """
        page = utils.intval(web.input().get('page', '0'))
        # 一次读取10条
        perpage = 10
        # 读取记录数
        r = proj_models.Partner.get_partners(page * perpage, perpage)
        if r.result:
            lst = []
            for p in r.result:
                lst.append('<li><img src="%(logo)s" width="42" height="42" title="%(name)s"> %(name)s</li>' % {
                                'logo': utils.get_media_url(p.logo, 3),
                                'name': p.name
                            })
            r.result = '<ul>%s</ul>' % ''.join(lst)
            return utils.json_encode(r)

        return '0'

    @auth_login(ajax = True)
    def aff_beento(self):
        """
        “去过”灵感信息
        """
        id = utils.intval(web.input().get('id', '0'))
        if id > 0:
            if afflatus_models.been_to(id, web.ctx.user.uid, 0, None):
                return 'OK'

        return 'NO'

    def aff_unbeento(self):
        """
        “取消去过”灵感信息
        """
        id = utils.intval(web.input().get('id', '0'))
        if id > 0:
            if afflatus_models.unbeen_to(id, web.ctx.user.uid):
                return 'OK'

        return 'NO'

    def aff_follow(self):
        """
        关注灵感信息
        """
        session = UserSession.current()
        if session.logined:
            id = utils.intval(web.input().get('id', '0'))
            # 关注灵感信息
            if afflatus_models.follow(id, session.uid) >= 0:
                return "OK"

        return "NO"

    def aff_unfollow(self):
        """
        取消关注灵感信息
        """
        session = UserSession.current()
        if session.logined:
            id = utils.intval(web.input().get('id', '0'))
            # 取消关注
            if afflatus_models.unfollow(id, session.uid):
                return "OK"

        return "NO"

    def auth_login(self):
        """
        登录验证
        """
        include_info = utils.intval(web.input().get('include_info', '0'))
        session = UserSession.current()
        if include_info == 1:
            # 包含登录信息
            if session.logined:
                return '''{
                        "uid": %s,
                        "name": "%s"
                    }''' % (session.uid, session.name)
            else:
                return 0
        else:
            # 不包含登录信息
            return session.logined and 1 or 0

class Index(object):
    """
    首页
    """
    def GET(self):
        import random
        # 读取读取特惠信息瀑布
        #discounts = discount_models.get_topN_discounts(14)
        # 读取灵感信息第一页
        affs = afflatus_models.get_all_afflatus_rand(20, None)
        # 分组后的特惠信息列表
        gTOP10 = storage(type1 = [], type2 = [], type3 = [])
        # 读取最新一周的甄选信息
        TOP10 = memoize(discount_models.get_last_TOP10, 300, False)()
        if TOP10:
            # 先进行随机排序了再分类
            # 可以减少一次循环处理
            TOP10[0].lst = random.sample(TOP10[0].lst, len(TOP10[0].lst))
            for d in TOP10[0].lst:
                # 这里排除掉航班类型的
                if d.type != 3:
                    #key = 'type%s' % d.type
                    # 只提取5条
                    if len(gTOP10['type1']) < 5:
                        gTOP10['type1'].append(d)
                        #gTOP10['type%s' % d.type].append(d)

                # 现在闪电特惠不再从TOP10中筛选了
                #if d.lightning:
                    # 这里处理闪电特惠
                #    key = 'type3'
                    # 只提取5条
                #    if len(gTOP10[key]) < 5:
                #        gTOP10[key].append(d)
        # 读取闪电特惠
        ls = memoize(discount_models.get_discounts_lightning_directing, 300, False)()
        if ls:
            # 先随机排序一次
            ls[0].lst = random.sample(ls[0].lst, len(ls[0].lst))
            for d in ls[0].lst:
                key = None
                if d.lightning == 1:
                    if len(gTOP10['type3']) < 5:
                        gTOP10['type3'].append(d)
                if d.directing == 1:
                    if len(gTOP10['type2']) < 5:
                        gTOP10['type2'].append(d)


        # 读取本周中随机的5条特惠信息
        rand5 = memoize(discount_models.get_last_TOP10_rand, 300, False)()
        # 获取第一页的合作商家
        partners = proj_models.Partner.get_partners(0, 10)
        # 将单向读取的枚举列表转换为可以重复读取的列表
        return render.index(affs, gTOP10, rand5, partners)

class Help(object):
    """
    帮助相关静态页显示
    """
    VIEWS = {
                'about': render.help.about,
                'followsite': render.help.followsite,
                'how-to-selected': render.help.how_to_selected,
                'contact-us': render.help.contact_us,
            }
    def GET(self, view):
        return self.VIEWS[view]()
